'use client';

import { useState, useRef, useEffect } from 'react';
import { cn } from '@/lib/utils';

interface OptimizedImageProps {
  src: string;
  alt: string;
  width?: number;
  height?: number;
  className?: string;
  priority?: boolean;
  placeholder?: 'blur' | 'empty';
  blurDataURL?: string;
  sizes?: string;
  quality?: number;
  loading?: 'lazy' | 'eager';
  onLoad?: () => void;
  onError?: () => void;
}

/**
 * 优化的图片组件
 * 支持懒加载、占位符、响应式图片和性能优化
 */
export function OptimizedImage({
  src,
  alt,
  width,
  height,
  className,
  priority = false,
  placeholder = 'empty',
  blurDataURL,
  sizes,
  quality = 75,
  loading = 'lazy',
  onLoad,
  onError,
}: OptimizedImageProps) {
  const [isLoaded, setIsLoaded] = useState(false);
  const [hasError, setHasError] = useState(false);
  const [isInView, setIsInView] = useState(priority);
  const imgRef = useRef<HTMLImageElement>(null);
  const observerRef = useRef<IntersectionObserver | null>(null);

  /**
   * 处理图片加载完成
   */
  const handleLoad = () => {
    setIsLoaded(true);
    onLoad?.();
  };

  /**
   * 处理图片加载错误
   */
  const handleError = () => {
    setHasError(true);
    onError?.();
  };

  /**
   * 设置 Intersection Observer 进行懒加载
   */
  useEffect(() => {
    if (priority || !imgRef.current) return;

    observerRef.current = new IntersectionObserver(
      entries => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            setIsInView(true);
            observerRef.current?.disconnect();
          }
        });
      },
      {
        rootMargin: '50px', // 提前50px开始加载
        threshold: 0.1,
      }
    );

    observerRef.current.observe(imgRef.current);

    return () => {
      observerRef.current?.disconnect();
    };
  }, [priority]);

  /**
   * 生成响应式图片URL
   */
  const generateImageUrl = (src: string, width?: number, quality?: number) => {
    // 如果是外部URL，直接返回
    if (src.startsWith('http')) {
      return src;
    }

    // 如果是Trae API图片，添加参数
    if (src.includes('trae-api-us.mchost.guru')) {
      const url = new URL(src);
      if (width) url.searchParams.set('w', width.toString());
      if (quality) url.searchParams.set('q', quality.toString());
      return url.toString();
    }

    // 本地图片处理
    return src;
  };

  /**
   * 生成srcSet用于响应式图片
   */
  const generateSrcSet = (src: string, quality?: number) => {
    if (src.startsWith('http') && !src.includes('trae-api-us.mchost.guru')) {
      return undefined;
    }

    const sizes = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
    return sizes
      .map(size => `${generateImageUrl(src, size, quality)} ${size}w`)
      .join(', ');
  };

  /**
   * 生成模糊占位符
   */
  const generateBlurDataURL = () => {
    if (blurDataURL) return blurDataURL;

    // 生成简单的模糊占位符
    return '';
  };

  // 错误状态
  if (hasError) {
    return (
      <div
        className={cn(
          'flex items-center justify-center bg-gray-100 dark:bg-gray-800 text-gray-400 dark:text-gray-600',
          className
        )}
        style={{ width, height }}
      >
        <svg className="w-8 h-8" fill="currentColor" viewBox="0 0 20 20">
          <path
            fillRule="evenodd"
            d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z"
            clipRule="evenodd"
          />
        </svg>
      </div>
    );
  }

  return (
    <div
      className={cn('relative overflow-hidden', className)}
      style={{ width, height }}
    >
      {/* 占位符 */}
      {placeholder === 'blur' && !isLoaded && (
        <div
          className="absolute inset-0 bg-gray-200 dark:bg-gray-700 animate-pulse"
          style={{
            backgroundImage: `url(${generateBlurDataURL()})`,
            backgroundSize: 'cover',
            backgroundPosition: 'center',
            filter: 'blur(10px)',
            transform: 'scale(1.1)',
          }}
        />
      )}

      {/* 加载指示器 */}
      {!isLoaded && placeholder === 'empty' && (
        <div className="absolute inset-0 bg-gray-100 dark:bg-gray-800 animate-pulse flex items-center justify-center">
          <svg
            className="w-8 h-8 text-gray-400 dark:text-gray-600"
            fill="currentColor"
            viewBox="0 0 20 20"
          >
            <path
              fillRule="evenodd"
              d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z"
              clipRule="evenodd"
            />
          </svg>
        </div>
      )}

      {/* 实际图片 */}
      {isInView && (
        <img
          ref={imgRef}
          src={generateImageUrl(src, width, quality)}
          srcSet={generateSrcSet(src, quality)}
          sizes={
            sizes || '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
          }
          alt={alt}
          width={width}
          height={height}
          loading={loading}
          decoding="async"
          onLoad={handleLoad}
          onError={handleError}
          className={cn(
            'transition-opacity duration-300',
            isLoaded ? 'opacity-100' : 'opacity-0',
            'w-full h-full object-cover'
          )}
        />
      )}
    </div>
  );
}

/**
 * 图片预加载Hook
 */
export function useImagePreload(src: string) {
  const [isLoaded, setIsLoaded] = useState(false);
  const [hasError, setHasError] = useState(false);

  useEffect(() => {
    const img = new Image();
    img.onload = () => setIsLoaded(true);
    img.onerror = () => setHasError(true);
    img.src = src;

    return () => {
      img.onload = null;
      img.onerror = null;
    };
  }, [src]);

  return { isLoaded, hasError };
}

/**
 * 批量图片预加载Hook
 */
export function useBatchImagePreload(srcs: string[]) {
  const [loadedCount, setLoadedCount] = useState(0);
  const [errorCount, setErrorCount] = useState(0);

  useEffect(() => {
    let loadedImages = 0;
    let errorImages = 0;

    const promises = srcs.map(src => {
      return new Promise<void>(resolve => {
        const img = new Image();
        img.onload = () => {
          loadedImages++;
          setLoadedCount(loadedImages);
          resolve();
        };
        img.onerror = () => {
          errorImages++;
          setErrorCount(errorImages);
          resolve();
        };
        img.src = src;
      });
    });

    Promise.all(promises);

    return () => {
      setLoadedCount(0);
      setErrorCount(0);
    };
  }, [srcs]);

  return {
    loadedCount,
    errorCount,
    totalCount: srcs.length,
    isAllLoaded: loadedCount + errorCount === srcs.length,
    progress: srcs.length > 0 ? (loadedCount + errorCount) / srcs.length : 0,
  };
}
